package com.beta.service.impl;

import com.baomidou.framework.service.impl.SuperServiceImpl;
import com.beta.service.IConfirmationCodesService;
import com.beta.em.ConfirmCodeType;
import com.beta.entity.ConfirmationCodes;
import com.beta.entity.Users;
import com.beta.mapper.ConfirmationCodesMapper;
import com.beta.service.ISmsService;
import com.beta.service.IUsersService;
import com.beta.service.ServiceException;
import com.beta.util.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Date;
import java.util.Objects;

/**
 *
 * ConfirmationCodes 表数据服务层接口实现类
 *
 */
@Service
public class ConfirmationCodesService extends SuperServiceImpl<ConfirmationCodesMapper, ConfirmationCodes> implements IConfirmationCodesService {

    @Autowired
    private ISmsService smsService;

    @Autowired
    private IUsersService usersService;

    @Override
    public void createCode(String phone, ConfirmCodeType type) {
        if (ConfirmCodeType.REGIST.equals(type)) {
            verifyUserExists(phone);
        }

        ConfirmationCodes conditionEntity = new ConfirmationCodes().setPhone(phone).setCodeType(type.getValue());
//        ConfirmationCodes confirmationCodes = selectOne(conditionEntity);
//        if (Objects.nonNull(confirmationCodes)) {
//            if (isExpiredConfirmationCode(confirmationCodes)) {
//                deleteSelective(conditionEntity);
//            } else {
//
//            }
//        }
        deleteSelective(conditionEntity);

        String code = RandomUtils.randomStringWithLength(6);
        ConfirmationCodes insertEntity = new ConfirmationCodes()
                .setCode(code)
                .setCodeType(type.getValue())
                .setCreatedAt(new Date())
                .setUpdatedAt(new Date())
                .setPhone(phone);
        insertSelective(insertEntity);
        new Thread(() -> {
            smsService.sendConfirmCode(phone, code);
        }).start();
    }

    private void verifyUserExists(String phone) {
        boolean exists = usersService.selectCount(new Users().setPhone(phone)) > 0;
        if (exists) {
            throw new ServiceException("user.register.exists");
        }
    }

    @Override
    public void validateCode(String phone, ConfirmCodeType type, String code) {
        if (StringUtils.isAnyBlank(phone, code) || Objects.isNull(type)) {
            throw new ServiceException("E000400");
        }
        ConfirmationCodes conditionEntity = new ConfirmationCodes()
                .setPhone(phone)
                .setCodeType(type.getValue())
                .setCode(code);
        ConfirmationCodes confirmationCodes = selectOne(conditionEntity);
        if (Objects.isNull(confirmationCodes)) {
            throw new ServiceException("E00104");
        }
        deleteSelective(conditionEntity);
    }

    private boolean isExpiredConfirmationCode(ConfirmationCodes confirmationCodes) {
        return new Date().toInstant().isAfter(confirmationCodes.getCreatedAt().toInstant().plus(Duration.ofMinutes(10)));
    }

}